package com.powergisol.gis.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.powergisol.gis.dao.BoreholeQueryMapper;
import com.powergisol.gis.dao.TabDataSettingMapper;
import com.powergisol.gis.dao.TabYcMapper;
import com.powergisol.gis.dao.TabZkMapper;
import com.powergisol.gis.dto.ExcavatingDTO;
import com.powergisol.gis.dto.SectionDTO;
import com.powergisol.gis.dto.VirtualDrillDTO;
import com.powergisol.gis.dto.ZkTcSwDTO;
import com.powergisol.gis.entity.*;
import com.powergisol.gis.exception.GlobalExceptionHandler;
import com.powergisol.gis.geom.GeoLineString;
import com.powergisol.gis.geom.GeoPoint;
import com.powergisol.gis.geom.GeoPolygon;
import com.powergisol.gis.service.*;
import com.powergisol.gis.util.FileUtil;
import com.powergisol.gis.util.Result;
import com.powergisol.gis.vo.*;
import com.vividsolutions.jts.geom.Coordinate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class TabZuanKongServiceImpl implements TabZuanKongService {
    @Autowired
    TabDataSettingService tabDataSettingService;
    @Autowired
    TabProjectService tabProjectService;
    @Autowired
    private TabZkMapper tabZkMapper;

    @Autowired
    private TabYcMapper tabYcMapper;

    @Autowired
    VirtualDrillService validationService;

    @Autowired
    BoreholeQueryMapper boreholeQueryMapper;

    @Autowired
    SectionService sectionService;

    @Autowired
    TabDataSettingMapper settingMapper;

    @Autowired
    SaveDataService saveDataService;
    @Autowired
    ExcavatingService excavatingService;
    @Value("${ZKLX}")
    private String ZKLX;

    /**
     * 钻孔列表接口
     *
     * @param serviceIds 服务ID集合
     * @return
     */
    @Override
    public Map<String, ZkTcSwVO> getZKData(Integer[] serviceIds) {
        //为了避免遍历式查询数据库，从而提高查询速度，所以写的复杂了点

        List<Integer> serviceIdList = Arrays.asList(serviceIds);
        List<TabDataSetting> setIdBySerID = tabDataSettingService.getSetIdBySerID(serviceIdList);
        Map<String, ZkTcSwVO> ZKMap = null;
        try {
            if (setIdBySerID.isEmpty() || setIdBySerID.size() <= 0) {
                throw new GlobalExceptionHandler("服务不存在");
            }
            //先获取 settingIds
            List<String> settingIds = new ArrayList<>();
            List<Integer> setIDs = new ArrayList<>();
            setIdBySerID.forEach(x -> {
                setIDs.add(x.getId());
                settingIds.add(String.valueOf(x.getId()));
            });
            //根据settingIds 找到钻孔
            List<ZuankongVO> zkBySettingId = tabZkMapper.getZKBySettingIdTwo(settingIds);
            ZKMap = new HashMap<>();
            List<ZkTcSwDTO> zkTcSwDTOList = new ArrayList<>();
            List<TabProject> tabProjectList = tabProjectService.getAllBySet(setIDs);

            for (ZuankongVO z : zkBySettingId) {
                for (TabDataSetting tabDataSetting : setIdBySerID) {
                    for (TabProject tabProject : tabProjectList) {
                        if (z.getSettingId().equals(tabDataSetting.getId()) && z.getSettingId().equals(tabProject.getSettingId())) {
                            ZkTcSwVO zkTcSwVO = new ZkTcSwVO();
                            ZkTcSwDTO zkTcSwDTO = new ZkTcSwDTO();

                            z.setGCMC(tabProject.getGCMC());

                            zkTcSwVO.setZuankongVO(z);

                            zkTcSwVO.setUuid(tabDataSetting.getUuid());
                            //将这个SettingId放到集合中后面当查询条件用

                            zkTcSwDTO.setSettingId(z.getSettingId());
                            //将SettingId存下来，后面组合map集合的键需要

                            z.setServiceId(tabDataSetting.getServiceId());

                            zkTcSwDTOList.add(zkTcSwDTO);

                            ZKMap.put(tabDataSetting.getServiceId() + "_" + z.getZKBH(), zkTcSwVO);
                        }
                    }
                }
            }
            //根据settingId查询水位
            List<TabZkShuiwei> tabZkShuiweiList = null;
            if (zkTcSwDTOList != null && !zkTcSwDTOList.isEmpty() && zkTcSwDTOList.size() > 0) {
                tabZkShuiweiList = tabZkMapper.getSWStWO(zkTcSwDTOList);
            }
            //根据settingId查询土层
            List<TuCengVO> tabZkTucengList = tabZkMapper.getTCSTWO(zkTcSwDTOList);
            if (null != tabZkShuiweiList || tabZkShuiweiList.size() > 0) {
                for (ZuankongVO zuankongVO : zkBySettingId) {
                    //将settingId相等并且ZKBH相等装进这个集合
                    List<TabZkShuiwei> tabZkShuiweis = new ArrayList<>();
                    for (TabZkShuiwei tabZkShuiwei : tabZkShuiweiList) {
                        //判断settingId与ZKBH是否满足条件
                        if (zuankongVO.getSettingId().equals(tabZkShuiwei.getSettingId()) && zuankongVO.getZKBH().equals(tabZkShuiwei.getZKBH())) {
                            tabZkShuiweis.add(tabZkShuiwei);
                        }
                    }
                    //对这个集合进行排序
                /* Collections.sort(tabZkShuiweis, new Comparator<TabZkShuiwei>() {
                     @Override
                     public int compare(TabZkShuiwei o1, TabZkShuiwei o2) {
                         return o2.getSWCH()-o1.getSWCH();
                     }
                 });*/
                    //找到相应钻孔存放的map
                    ZkTcSwVO zkTcSwVO = ZKMap.get(zuankongVO.getServiceId() + "_" + zuankongVO.getZKBH());
                    //将这个排好序的集合放到对应的map的对应属性中
                    zkTcSwVO.setTabZkShuiweis(tabZkShuiweis);
                }
            }
            for (ZuankongVO zuankongVO : zkBySettingId) {
                //将settingId相等并且ZKBH相等装进这个集合
                List<TuCengVO> tabZkTucengs = new ArrayList<>();
                BigDecimal sd = new BigDecimal(0);
                for (TuCengVO tabZkTuceng : tabZkTucengList) {
                    //判断settingId与ZKBH是否满足条件
                    if (zuankongVO.getSettingId().equals(tabZkTuceng.getSettingId()) && zuankongVO.getZKBH().equals(tabZkTuceng.getZKBH())) {
                        tabZkTuceng.setCDGC(zuankongVO.getZKBG().subtract(tabZkTuceng.getTCCDSD()));
                        sd = sd.add(tabZkTuceng.getTCHD());
                        tabZkTucengs.add(tabZkTuceng);
                    }
                }
                //对这个集合进行排序
                tabZkTucengs.sort(Comparator.comparing(TabZkTuceng::getTCZCBH, Comparator.nullsFirst(Comparator.naturalOrder())).reversed());
                //找到相应钻孔存放的map
                ZkTcSwVO zkTcSwVO = ZKMap.get(zuankongVO.getServiceId() + "_" + zuankongVO.getZKBH());
                BigDecimal zksd = zkTcSwVO.getZuankongVO().getZKSD();
                if (zksd == null || zksd == new BigDecimal(0)) {
                    zkTcSwVO.getZuankongVO().setZKSD(sd);
                }
                //将这个排好序的集合放到对应的map的对应属性中
                zkTcSwVO.setTabZkTucengs(tabZkTucengs);
            }
        } catch (Exception e) {
            throw new GlobalExceptionHandler(404, e.getMessage());
        }

        return ZKMap;
    }

    @Override
    public Result simulateZuanKong(SimulateZuanKongVo vo) {
        Result r = new Result();
        List<MoniZuankongVo> vos = new ArrayList<>();
        ObjectMapper mapper = new ObjectMapper();
        try {
            TabYc yc = tabYcMapper.selectYcByUuid(vo.getUuid());
            String plane = FileUtil.getContent(yc.getPlane());
            GeoPoint point = new GeoPoint(vo.getX(), vo.getY(), vo.getZ());

            List<VirtualDrillDTO> list = validationService.getIntersection(point, plane);
            if (list.isEmpty()) {
                return r;
            }
            //根据uuid查询岩层分层设置
            List<TabMarkerColor> listColors = settingMapper.listByMarkers(vo.getUuid());

            List<TabZuankong> listZk = new ArrayList<>();//存放钻孔数据
            List<TabZkTuceng> listTc = new ArrayList<>();//存放土层数据
            Double tccdsd = 0d;//层底深度
            Double tchd = 0d;//岩层厚度
            Double zksd = 0d;
            String x = BigDecimal.valueOf(vo.getX()).setScale(6, BigDecimal.ROUND_HALF_UP).toString();
            x = x.substring(x.lastIndexOf(".") + 1, x.length());
            String zkbh = ZKLX + x;
            BigDecimal zkbg = new BigDecimal(vo.getZ()).setScale(6, BigDecimal.ROUND_HALF_UP);
            for (int i = list.size() - 1; i >= 0; i--) {
                if (i % 2 != 0) {
                    VirtualDrillDTO dto = list.get(i - 1);
                    tchd = list.get(i - 1).getGeoPoint().getZ() - list.get(i).getGeoPoint().getZ();
                    tccdsd = vo.getZ() - list.get(i).getGeoPoint().getZ();
                    TabZuankong zk = new TabZuankong();
                    TabZkTuceng tc = new TabZkTuceng();

                    MoniZuankongVo moniZuankongVo = new MoniZuankongVo();
                    moniZuankongVo.setTCHD(new BigDecimal(tchd).setScale(6, BigDecimal.ROUND_HALF_UP));
                    moniZuankongVo.setZKBG(zkbg);
                    moniZuankongVo.setZKBH(zkbh);
                    moniZuankongVo.setZKLX(ZKLX);
                    moniZuankongVo.setZKX(new BigDecimal(vo.getX()).setScale(6, BigDecimal.ROUND_HALF_UP));
                    moniZuankongVo.setZKY(new BigDecimal(vo.getY()).setScale(6, BigDecimal.ROUND_HALF_UP));
                    moniZuankongVo.setSettingId(vo.getSettingId());

                    zk.setSettingId(vo.getSettingId());
                    zk.setZKBH(zkbh);
                    zk.setZKLX(ZKLX);
                    zk.setZKOX(new BigDecimal(vo.getX()).setScale(6, BigDecimal.ROUND_HALF_UP));
                    zk.setZKOY(new BigDecimal(vo.getY()).setScale(6, BigDecimal.ROUND_HALF_UP));
                    zk.setZKX(new BigDecimal(vo.getX()).setScale(6, BigDecimal.ROUND_HALF_UP));
                    zk.setZKY(new BigDecimal(vo.getY()).setScale(6, BigDecimal.ROUND_HALF_UP));
                    zk.setZKBG(zkbg);
                    zk.setDataIndex(i);
                    listZk.add(zk);

                    zksd = zksd + tchd;
                    tc.setTCHD(new BigDecimal(tchd).setScale(6, BigDecimal.ROUND_HALF_UP));
                    moniZuankongVo.setTCCDSD(new BigDecimal(tccdsd).setScale(6, BigDecimal.ROUND_HALF_UP));
                    tc.setSettingId(vo.getSettingId());
                    tc.setZKBH(zkbh);
                    tc.setDataIndex(i);
                    tc.setTCCDSD(new BigDecimal(tccdsd).setScale(6, BigDecimal.ROUND_HALF_UP));

                    String level = dto.getLevel() + "";
                    List<TabMarkerColor> configs = listColors.stream().filter((TabMarkerColor b) -> level.equals(b.getZkfc().toString()))
                            .collect(Collectors.toList());
                    tc.setTCMC(configs.get(0).getDrillMarker());
                    tc.setTCBH(configs.get(0).getTcbh());
                    tc.setTCSDCY(configs.get(0).getTcsdcy());
                    tc.setTCMS(configs.get(0).getTcms());
                    moniZuankongVo.setTCMC(configs.get(0).getDrillMarker());
                    moniZuankongVo.setTCBH(configs.get(0).getTcbh());
                    moniZuankongVo.setTCSDCY(configs.get(0).getTcsdcy());
                    moniZuankongVo.setTCMS(configs.get(0).getTcms());
                    listTc.add(tc);
                    vos.add(moniZuankongVo);
                }

            }
            //存库（settingId为-1时不存库）
            if (listZk.size() > 0 && !("-1").equals(vo.getSettingId())) {
                for (TabZuankong zk : listZk) {
                    zk.setZKSD(new BigDecimal(zksd).setScale(6, BigDecimal.ROUND_HALF_UP));
                }
                saveDataService.saveBatch(listZk);
            }

            //模拟钻孔的土层（settingId为-1时不存库）
            if (listTc.size() > 0 && !("-1").equals(vo.getSettingId())) {
                saveDataService.saveBatch(listTc);
            }
            r.setData(vos);

        } catch (Exception e) {
            e.printStackTrace();
            e.getMessage();
            return r.failure(500, e.getMessage());
        }
        return r;
    }

    /**
     * 钻孔新增
     *
     * @param zkAddVO
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public Result addZK(ZKAddVO zkAddVO) {
        try {
            long begin = System.currentTimeMillis();
            List<TabZuankong> zuankongs = new ArrayList<>();
            TabZuankong tempZuankong = null;
            for (int i = 0; i < zkAddVO.getTabZkTucengs().size(); i++) {
                tempZuankong = new TabZuankong();
                zkAddVO.getTabZkTucengs().get(i).setDataIndex(i + 1);
                BeanUtils.copyProperties(zkAddVO.getZuankong(), tempZuankong);
                tempZuankong.setDataIndex(i + 1);
                tempZuankong.setSettingId(zkAddVO.getSettingId());
                tempZuankong.setZKBH(zkAddVO.getZkbh());
                zkAddVO.getTabZkTucengs().get(i).setSettingId(zkAddVO.getSettingId());
                zkAddVO.getTabZkTucengs().get(i).setZKBH(zkAddVO.getZkbh());
                String point = "POINT("+tempZuankong.getZKX()+" "+tempZuankong.getZKY()+")";
                TabArea tabArea = boreholeQueryMapper.getAreaByPoint(point);
                tempZuankong.setTCMC(zkAddVO.getTabZkTucengs().get(i).getTCMC());
                tempZuankong.setTCHD(zkAddVO.getTabZkTucengs().get(i).getTCHD());
                tempZuankong.setTCCDSD(zkAddVO.getTabZkTucengs().get(i).getTCCDSD());
                tempZuankong.setCoor(point);
                tempZuankong.setGCMC(zkAddVO.getZuankong().getGCMC());
                tempZuankong.setCode(null == tabArea?null:tabArea.getCode());
                zuankongs.add(tempZuankong);
            }
            for (TabZkTuceng tabZkTuceng : zkAddVO.getTabZkTucengs()) {
                if (tabZkTuceng.getTCYCBH() != null && tabZkTuceng.getTCCYCBH() == null) {
                    tabZkTuceng.setTCBH(tabZkTuceng.getTCZCBH() + "-" + tabZkTuceng.getTCYCBH());
                } else if (tabZkTuceng.getTCCYCBH() != null && tabZkTuceng.getTCYCBH() == null) {
                    tabZkTuceng.setTCBH(tabZkTuceng.getTCZCBH() + "-" + tabZkTuceng.getTCCYCBH());
                } else if (tabZkTuceng.getTCCYCBH() == null && tabZkTuceng.getTCYCBH() == null) {
                    tabZkTuceng.setTCBH(tabZkTuceng.getTCZCBH() + "");
                } else {
                    tabZkTuceng.setTCBH(tabZkTuceng.getTCZCBH() + "-" + tabZkTuceng.getTCYCBH() + "-" + tabZkTuceng.getTCCYCBH());
                }
            }
            if (!zkAddVO.getTabZkShuiweis().isEmpty()) {
                for (TabZkShuiwei tabZkShuiwei : zkAddVO.getTabZkShuiweis()) {
                    checkData(String.valueOf(tabZkShuiwei.getSWCJMS()), "2");
                    checkData(String.valueOf(tabZkShuiwei.getSWSD()), "1");
                    tabZkShuiwei.setSettingId(zkAddVO.getSettingId());
                    tabZkShuiwei.setZKBH(zkAddVO.getZkbh());
                }
            }

            List<String> zkbhs = tabZkMapper.getZuank(zkAddVO.getSettingId());
            boolean flag = false;
            for (String zkbh : zkbhs) {
                if (zkbh.equals(zkAddVO.getZkbh())) {
                    flag = true;
                }
            }
            if (flag) {
                throw new GlobalExceptionHandler(400, "钻孔已存在");
            }
            long l = System.currentTimeMillis();
            int zk = tabZkMapper.addZK(zuankongs);
            int tc = tabZkMapper.addZKTC(zkAddVO.getTabZkTucengs());
            log.info("钻孔新增+土层新增耗时{}" + (System.currentTimeMillis() - l));
            if (!zkAddVO.getTabZkShuiweis().isEmpty() && zkAddVO.getTabZkShuiweis().size() > 0) {
                tabZkMapper.addZKSW(zkAddVO.getTabZkShuiweis());
            }
            if (zk > 0 && tc > 0) {
                ZkTcSwVO details = getDetails(new ZkTcSwDTO(zkAddVO.getSettingId(), zkAddVO.getZkbh()));
                if (zkAddVO.getIsUp().equals("0")) {
                    details.setResult("钻孔修改成功");
                } else {
                    details.setResult("钻孔新增成功");
                }

                log.info("钻孔新增耗时{}", (System.currentTimeMillis() - begin));
                return new Result().success(details);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new GlobalExceptionHandler(500, e.getMessage());
        }
        return new Result().failure(400, "钻孔新增失败");
    }

    /**
     * 钻孔的所有类型
     *
     * @return
     */
    @Override
    public List<String> getAllClass() {
        String pattern = "([1-9]\\d*\\.?\\d*)|(0\\.\\d*[1-9])";
        List<String> zkClass = tabZkMapper.getAllClass();
        for (int i = 0; i < zkClass.size(); i++) {
            //这个contains()中的空字符很特殊，不同于普通空格
            if (zkClass.get(i).contains("　")) {
                String replace = zkClass.get(i).replace("　", "");
                if (!zkClass.contains(replace)) {
                    zkClass.set(i, replace);
                } else {
                    zkClass.remove(i);
                    i--;
                }
            } else if (zkClass.get(i).equals("null")) {
                zkClass.remove(i);
                i--;
            } else if (zkClass.get(i).contains(" ")) {//普通的空格判断
                String replace = zkClass.get(i).replace(" ", "");
                if (!zkClass.contains(replace)) {
                    zkClass.set(i, replace);
                } else {
                    zkClass.remove(i);
                    i--;
                }
            } else if (zkClass.get(i).matches(pattern)) {
                zkClass.remove(i);
                i--;
            }
        }
        return zkClass;
    }

    /**
     * 钻孔(包含土层、水位)详情
     *
     * @param zkTcSwDTO
     * @return
     */
    @Override
    public ZkTcSwVO getDetails(ZkTcSwDTO zkTcSwDTO) {
        long begin = System.currentTimeMillis();
        ZkTcSwVO zkTcSwVO = new ZkTcSwVO();

        ZuankongVO zKs = new ZuankongVO();
        List<ZuankongVO> tempList = tabZkMapper.getZuan(zkTcSwDTO.getSettingId());
        tempList.forEach(t -> {
            if (t.getZKBH().equals(zkTcSwDTO.getZkbh())) {
                BeanUtils.copyProperties(t, zKs);
            }
        });
        TabProject one = tabProjectService.getOne(zkTcSwDTO.getSettingId());

        TabDataSetting tabDataSetting = tabDataSettingService.getOne(zkTcSwDTO.getSettingId());

        zKs.setGCMC(one.getGCMC());
        zKs.setGCBH(one.getGCBH());
        zKs.setServiceId(tabDataSetting.getServiceId());
        zkTcSwVO.setZuankongVO(zKs);
        List<TuCengVO> tcs = tabZkMapper.getTcs(zkTcSwDTO.getSettingId(), zkTcSwDTO.getZkbh());
        BigDecimal sd = new BigDecimal(0);
        for (TuCengVO tc : tcs) {
            sd = sd.add(tc.getTCHD());
            tc.setCDGC(zKs.getZKBG().subtract(tc.getTCCDSD()));
        }
        tcs.sort(Comparator.comparing(TabZkTuceng::getTCCDSD));
        zkTcSwVO.setTabZkTucengs(tcs);
        List<TabZkShuiwei> sws = tabZkMapper.getSws(zkTcSwDTO.getSettingId(), zkTcSwDTO.getZkbh());
        BigDecimal zksd = zkTcSwVO.getZuankongVO().getZKSD();
        if (zksd == null || zksd == new BigDecimal(0)) {
            zkTcSwVO.getZuankongVO().setZKSD(sd);
        }
        zkTcSwVO.setTabZkShuiweis(sws);
        zkTcSwVO.setUuid(tabDataSetting.getUuid());
        log.info("钻孔详情耗时{}", (System.currentTimeMillis() - begin));
        return zkTcSwVO;
    }

    /**
     * 钻孔修改
     *
     * @param zkAddVO
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public Result updateZK(ZKAddVO zkAddVO) {


//        try {
           /* ZkTcSwDTO zkTcSwDTO = new ZkTcSwDTO();
            zkTcSwDTO.setSettingId(zkAddVO.getSettingId());
            zkTcSwDTO.setZkbh(zkAddVO.getZkbh());

            for (TabZkShuiwei tabZkShuiwei : zkAddVO.getTabZkShuiweis()) {
                tabZkShuiwei.setZKBH(zkAddVO.getZkbh());
                tabZkShuiwei.setSettingId(zkAddVO.getSettingId());
            }*/
            /*//tcAddList装新增的土层
            List<TabZkTuceng> tcAddList = new ArrayList<>();
            //tcUpdateList装修改的集合
            List<TabZkTuceng> tcUpdateList = new ArrayList<>();
            for (TabZkTuceng tabZkTuceng : zkAddVO.getTabZkTucengs()) {
                if (tabZkTuceng.getId() == null || tabZkTuceng.getId() == 0) {
                    tcAddList.add(tabZkTuceng);
                } else {
                    tcUpdateList.add(tabZkTuceng);
                }
            }
            //swAddList装新增的集合
            List<TabZkShuiwei> swAddList = new ArrayList<>();
            //swUpdateList装修改的集合
            List<TabZkShuiwei> swUpdateList = new ArrayList<>();
            for (TabZkShuiwei tabZkShuiwei : zkAddVO.getTabZkShuiweis()) {
                if (tabZkShuiwei.getId() == null || tabZkShuiwei.getId() == 0) {
                    swAddList.add(tabZkShuiwei);
                } else {
                    swUpdateList.add(tabZkShuiwei);
                }
            }
            //查询以前的土层有哪些id
            List<TuCengVO> tc1 = tabZkMapper.getTcs(zkAddVO.getSettingId(), zkAddVO.getZkbh());
            //查询以前的水位有哪些id
            List<TabZkShuiwei> sws = tabZkMapper.getSwse(zkAddVO.getSettingId(), zkAddVO.getZkbh());
            List<Integer> swIds = sws.stream().map(s -> s.getId()).collect(Collectors.toList());
            //将编辑中带有ID的（带有ID说明是修改），把id收集起来
            List<Integer> tcListIds = tcUpdateList.stream().map(t -> t.getId()).collect(Collectors.toList());
            List<Integer> swListIds = swUpdateList.stream().map(s -> s.getId()).collect(Collectors.toList());
            //比较以前的ID集合与现在ID集合的区别，如果以前有，现在没有，说明在编辑土层的时候删掉了，那么就将以前土层的根据ID删除
            //如果以前有，现在也有，说明土层没有删除。因为新增已经单独提出来了，那么就全是修改


            for (TuCengVO tcId : tc1) {
                if (!tcListIds.contains(tcId.getId())) {


                    tabZkMapper.deleteZkByIndex(zkTcSwDTO, tcId.getDataIndex());
                    tabZkMapper.deletetcById(tcId.getId());
                    log.info("删除了id为{}的土层", tcId.getId());
                }
            }

            //比较以前的ID集合与现在ID集合的区别，如果以前有，现在没有，说明在编辑水位的时候删掉了，那么就将以前水位的根据ID删除
            //如果以前有，现在也有，说明土层没有删除。因为新增已经单独提出来了，那么就全是修改
            for (Integer swId : swIds) {
                if (!swListIds.contains(swId)) {
                    tabZkMapper.deleteswById(swId);
                    log.info("删除了id为{}的水位", swId);
                }
            }
            List<TabZuankong> zuankongList = new ArrayList<>();
            //获取当前最大dataIndex
            int maxDataIndex = tabZkMapper.getMaxDataIndex(zkTcSwDTO);

            if (!tcAddList.isEmpty() && tcAddList.size() > 0) {
                for (TabZkTuceng tabZkTuceng : tcAddList) {
                    maxDataIndex++;
                    //新增多少个土层就新增多少个钻孔记录，他们的dataIndex相同
                    TabZuankong zuankong = new TabZuankong();
                    BeanUtils.copyProperties(zkAddVO.getZuankong(), zuankong);

                    zuankong.setSettingId(zkAddVO.getSettingId());
                    zuankong.setDataIndex(maxDataIndex);

                    zuankongList.add(zuankong);
                    tabZkTuceng.setDataIndex(maxDataIndex);
                }
                //开始新增
                int t = tabZkMapper.addZKTC(tcAddList);
                int i = tabZkMapper.addZK(zuankongList);
                log.info("钻孔新增{}条,土层新增{}条", i, t);
            }
            if (!swAddList.isEmpty() && swAddList.size() > 0) {
                int s = tabZkMapper.addZKSW(swAddList);
                log.info("水位新增{}条", s);
            }

            int zk = tabZkMapper.updateZuankong(zkAddVO.getZuankong(), zkTcSwDTO);

            int tc = 0;
            if (!tcUpdateList.isEmpty() && tcUpdateList.size() > 0) {
                tc = tabZkMapper.updateTC(tcUpdateList);
            }
            int sw = 0;
            if (!swUpdateList.isEmpty() && swUpdateList.size() > 0) {
                sw = tabZkMapper.updateSW(swUpdateList);
            }
            log.info("钻孔修改{}条,土层修改{}条,水位修改{}条", zk, tc, sw);

            ZkTcSwVO details = getDetails(new ZkTcSwDTO(zkTcSwDTO.getSettingId(), zkTcSwDTO.getZkbh()));*/
            List<TabZkShuiwei> shuiweis = tabZkMapper.getSwBySet(zkAddVO.getSettingId());
            List<TabZkTuceng> tucengs = tabZkMapper.getTcBySet(zkAddVO.getSettingId());
            List<TabZuankong> zuankongs = tabZkMapper.getZkBySet(zkAddVO.getSettingId());
            List<Integer> tcIds = tucengs.stream().filter(s -> s.getZKBH().equals(zkAddVO.getZkbh())).collect(Collectors.toList()).stream().map(x -> x.getId()).collect(Collectors.toList());


            List<Integer> swIds = shuiweis.stream().filter(s -> s.getZKBH().equals(zkAddVO.getZkbh())).collect(Collectors.toList()).stream().map(x -> x.getId()).collect(Collectors.toList());
            List<Integer> zkIds = zuankongs.stream().filter(s -> s.getZKBH().equals(zkAddVO.getZkbh())).collect(Collectors.toList()).stream().map(x -> x.getId()).collect(Collectors.toList());

            if (swIds.size() > 0 && !swIds.isEmpty()) {
                tabZkMapper.deleteSw(swIds);
            }
            if (tcIds.size() > 0 && !tcIds.isEmpty()) {
                tabZkMapper.deleteTc(tcIds);
            }
            if (zkIds.size() > 0 && !zkIds.isEmpty()) {
                tabZkMapper.deleteZk(zkIds);
            }


            Result result = addZK(zkAddVO);
            return result;
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new GlobalExceptionHandler(500, e.getMessage());
//        }
    }


    /**
     * 删除钻孔
     *
     * @param zkTcSwDTO
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public Result deleteZK(List<ZkTcSwDTO> zkTcSwDTO) {
        log.info("用户删除钻孔，参数{}", zkTcSwDTO.toString());
        try {
            int sw = tabZkMapper.deleteSWs(zkTcSwDTO);
            int tc = tabZkMapper.deleteTCs(zkTcSwDTO);
            int zk = tabZkMapper.deleteZKs(zkTcSwDTO);
            log.info("受影响条数，钻孔{}条,土层{}条,水位{}条", zk, tc, sw);
            return new Result(200, "删除钻孔成功");
        } catch (Exception e) {
            e.printStackTrace();
            throw new GlobalExceptionHandler(400, "钻孔删除异常");
        }
    }

    //    @Override
//    public Result sliceZuanKong(SliceZuanKongVo vo) {
//        Result r = new Result();
//        try {
//            List<GeoPolygon> polygons = new ArrayList<>();
//
//            List<List<double[]>> list = vo.getPoint();
//
//            for (List<double[]> dList : list) {
//                List<Coordinate> coordinates = new ArrayList<>();
////                List<GeoLineString> lines = new ArrayList<>();
//                for (int i = 0; i < dList.size(); i++) {
//                    double[] d = dList.get(i);
//                    Coordinate coordinate = new Coordinate(d[0], d[1], d[2]);
//                    coordinates.add(coordinate);
//                }
////                GeoLineString line = new GeoLineString(dList.get(0)[0],dList.get(0)[1],dList.get(1)[0],dList.get(1)[1]);
////                for (int i = dList.size() - 1; i >= 0; i--) {
////                    double[] d = dList.get(i);
////                    Coordinate coordinate = new Coordinate(d[0], d[1], d[2] - vo.getH());
////                    coordinates.add(coordinate);
////                }
////                coordinates.add(new Coordinate(dList.get(0)[0], dList.get(0)[1], dList.get(0)[2]));
//                Coordinate[] objects = coordinates.toArray(new Coordinate[coordinates.size()]);
//                GeoPolygon polygon = new GeoPolygon(objects);
//                polygons.add(polygon);
//            }
//            TabYc yc = tabYcMapper.selectYcByUuid(vo.getUuid());
//            String plane = FileUtil.getContent(yc.getPlane());
//            List<SectionDTO> listDto = sectionService.createSection(polygons, plane);
//            r.setData(listDto);
//        } catch (IOException e) {
//            e.printStackTrace();
//            r.failure(500, "生成切面失败");
//        }
//        return r;
//    }
    @Override
    public Result sliceZuanKong(SliceZuanKongVo vo) {
        Result r = new Result();
        try {
            List<GeoLineString> sections = new ArrayList<>();

            List<List<List<Double>>> list = vo.getPoint();

            for (List<List<Double>> dList : list) {

                GeoLineString line = new GeoLineString(dList.get(0).get(0), dList.get(0).get(1), dList.get(0).get(2), dList.get(1).get(0), dList.get(1).get(1), dList.get(1).get(2));
                sections.add(line);
            }
            TabYc yc = tabYcMapper.selectYcByUuid(vo.getUuid());
            String plane = FileUtil.getContent(yc.getPlane());
            List<SectionDTO> listDto = sectionService.createSectionByLine(sections, plane, null == vo.getHeight() ? 1000d : vo.getHeight());
            r.setData(listDto);
        } catch (IOException e) {
            e.printStackTrace();
            r.failure(500, "生成切面失败");
        }
        return r;
    }

    @Override
    public Result holeZuanKong(SliceZuanKongVo vo) {
        Result r = new Result();
        List<Coordinate> coordinates = new ArrayList<>();
        List<double[]> list = vo.getHolePoint();
        for (int i = 0; i < list.size(); i++) {
            double[] d = list.get(i);
            Coordinate coordinate = new Coordinate(d[0], d[1], d[2]);
            coordinates.add(coordinate);
        }
        Coordinate[] objects = coordinates.toArray(new Coordinate[coordinates.size()]);
        GeoPolygon polygon = new GeoPolygon(objects);
        TabYc yc = tabYcMapper.selectYcByUuid(vo.getUuid());
        String plane = FileUtil.getContent(yc.getPlane());
        try {
            ExcavatingDTO dto = excavatingService.createExcavating(polygon, vo.getHeight(), plane);
            r.setData(dto);
        } catch (IOException e) {
            e.printStackTrace();
            r.failure(500, "生成挖坑失败");
        }
        return r;
    }

    @Override
    public Result zkfcSort(String uuid) {

        Result result = new Result();

        TabYc tabYc = tabYcMapper.selectYcByUuid(uuid);

        if (null == tabYc) {
            throw new GlobalExceptionHandler(404, "岩层不存在");
        }

        List<Map<String, Object>> data = tabZkMapper.getZkfcSort(tabYc.getSettingId());

        result.setData(data);

        return result;
    }

    private void checkData(String str, String type) throws RuntimeException {
       if(!StringUtils.isEmpty(str)){
           if (StringUtils.isNotBlank(str) && type.equals("1")) {
               BigDecimal decimal = new BigDecimal(str);
               if (decimal.toString().length()>12) {
                   throw new GlobalExceptionHandler(500, "稳定水位字符位长度不能大于12");
               }
           } else if (StringUtils.isNotBlank(str) && type.equals("2")) {
               BigDecimal bigDecimal = new BigDecimal(str);
               if (bigDecimal.toString().length()>12) {
                   throw new GlobalExceptionHandler(500, "初见水位埋深字符位长度不能大于12");
               }
           }
       }
    }
}
